package com.vinjogames.gfx;

import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.PointF;

import com.vinjogames.util.GameClock;
import com.vinjogames.util.VertexBuffer;

public class Image {	
	private float mGLWidth;
	private float mGLHeight;
	
	private int mFrames = 1;
	private long mAnimTime = 0;
	private long mDuration = 1000;
	
	private float mAngle;
	private boolean mLeftPivot = false;
	private boolean mFlip = false;
	
	// Texture stuff
	private FloatBuffer mTextureBuffer;
	private int[] mTextures;
	private int[] mAnimStarts;

	private FloatBuffer mVertexBuffer;

	private float vertices[];

	public Image(int graphic, float glWidth, float glHeight){
		mGLWidth  = glWidth;
		mGLHeight = glHeight;
		mTextures = SpriteSheet.getInstance().getTexture(graphic);
		mFrames   = mTextures.length;
		mDuration = mFrames * 100;//TODO:  define num of millis per frame
		mAnimStarts = new int[]{0};
		calculateVertices();

		float texture[] = {
				0.0f, 1.0f,
				0.0f, 0.0f,
				1.0f, 1.0f,
				1.0f, 0.0f
		};
		
		mTextureBuffer = VertexBuffer.getVertexBuffer(texture);
	}
	
	public Image(int graphic, float glWidth, float glHeight, boolean isAnimation){
		mGLWidth  = glWidth;
		mGLHeight = glHeight;
		mTextures = AnimationSheet.getInstance().getTexture(graphic);
		mFrames   = mTextures.length;
		mDuration = mFrames * 100;//TODO:  define num of millis per frame
		mAnimStarts = new int[]{0};
		calculateVertices();

		float texture[] = {
				0.0f, 1.0f,
				0.0f, 0.0f,
				1.0f, 1.0f,
				1.0f, 0.0f
		};
		
		mTextureBuffer = VertexBuffer.getVertexBuffer(texture);
	}
	
	
	public void setAnimations(int[] anims){
		mAnimStarts = anims;
	}
	
	public int getLastFrame(int i){
		if(i >= mAnimStarts.length || i < 0){
			return mFrames;
		}
		if(mAnimStarts.length == 1){ return 0; }
		
		if(i == mAnimStarts.length -1){
			return mFrames;
		}	
		return mAnimStarts[i+1];
	}
	
	public void calculateVertices(){
		vertices = new float[]{
				-mGLWidth/2,-mGLHeight/2,	0, // V2
				-mGLWidth/2, mGLHeight/2,	0, // V1
				 mGLWidth/2,-mGLHeight/2,	0, // V3
				 mGLWidth/2, mGLHeight/2,	0  // V4
		};
		mVertexBuffer = VertexBuffer.getVertexBuffer(vertices);
	}

	public void draw(GL10 gl, PointF location){
		draw(gl, location.x, location.y);
	}
	
	public void draw(GL10 gl, PointF location, int state){
		int frame = getCurrentFrame(GameClock.getInstance().getTime(), state);
		draw(gl, location.x, location.y, 1,1,1,1, frame);
	}
	
	public void draw(GL10 gl, PointF location, int state, float r, float g, float b, float a){
		int frame = getCurrentFrame(GameClock.getInstance().getTime(), state);
		draw(gl, location.x, location.y, r,g,b,a, frame);
	}
	
	public void draw(GL10 gl, float x, float y){
		draw(gl, x, y, 1,1,1,1, getCurrentFrame(GameClock.getInstance().getTime(),0));
	}

	public void draw(GL10 gl, float x, float y, float r, float g, float b, float a){
		draw(gl, x, y, r,g,b,a,getCurrentFrame(GameClock.getInstance().getTime(),0));
	}
			
	public void draw(GL10 gl, float x, float y, float r, float g, float b, float a, int frame){
		gl.glPushMatrix();
		
		// Bind Texture
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextures[frame]);

		// Point to Buffers
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

		// Set Face
		gl.glFrontFace(GL10.GL_CW);
		// Point to buffer
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
		gl.glColor4f(r, g, b, a);
		gl.glTranslatef(x, y, 0);	

		if(mFlip){
			gl.glScalef(-1, 1, 1);
		}
		if(mAngle != 0){		
			gl.glRotatef(mAngle, 0, 0, 1);	
		}
		
		if(mLeftPivot){
			gl.glTranslatef(getWidth() * 0.5f, 0, 0);
		}
		
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);//vertices.length / 3);

		// Disable Client State before Leaving
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glColor4f(1, 1, 1, 1);
		gl.glPopMatrix();
	}
	
	private int getCurrentFrame(long now, int state){
		int startFrame = this.mAnimStarts[state];
		int lastFrame = this.getLastFrame(state);
		int numFrames = lastFrame - startFrame;

		if(numFrames < 2) return 0;
		if(mAnimTime == 0) mAnimTime = now;
		return startFrame + (int)(((now-mAnimTime) % (mDuration)) * numFrames/mDuration);
	}

	public int getFrames(){ return mFrames; }
	public void setLeftPivot(){ mLeftPivot = true; }
	public void rotate(float angle){ mAngle = angle; }
	public void rotate(){ mAngle++; }
	public float getWidth() { return mGLWidth; }
	public float getHeight() { return mGLHeight; }
	public void setWidth(float width) { mGLWidth = width; calculateVertices(); }
	public void setHeight(float height) { mGLHeight = height; calculateVertices(); }
	public void setFlip(boolean flip){ mFlip = flip; }
	public boolean isFlipped() { return mFlip; }
}